<?php
/**
 * Created by PhpStorm.
 * User: qixiuxiu
 * Date: 2017/4/6
 * Time: 15:16
 */
namespace Simplex;

use Symfony\Component\HttpFoundation\Request;//引入请求类
use Symfony\Component\HttpFoundation\Response;//引入返回类
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;//引参数解析器
use Symfony\Component\HttpKernel\Controller\ControllerResolver;//引控制器解析器
use Symfony\Component\Routing\Exception\ResourceNotFoundException;//引异常类
use Symfony\Component\Routing\Matcher\UrlMatcher;//引UrlMatcher实例URL，U基于路由匹配URL
use Symfony\Component\EventDispatcher\EventDispatcher;//引入事件派遣类

/*
 * 处理请求的逻辑类
 * */
class Framework{
    protected $matcher;
    protected $controllerResolver;
    protected $argumentResolver;
    protected $dispatcher;
    
    //构造函数:匹配URL，控制器解析器，参数解析器
    public function __construct(EventDispatcher $dispatcher,UrlMatcher $matcher, ControllerResolver $controllerResolver, ArgumentResolver $argumentResolver)
    {
        $this->dispatcher = $dispatcher;
        $this->matcher = $matcher;
        $this->controllerResolver = $controllerResolver;
        $this->argumentResolver = $argumentResolver;
    }

    public function handle(Request $request)
    {
        $this->matcher->getContext()->fromRequest($request);

        try{
            //渲染的完成依靠的是一个外部函数（render_template()） 对它传入提取自URL的属性（attributes）。
            $request->attributes->add($this->matcher->match($request->getPathInfo()));

            //获得与请求相关联的Controller实例
            $controller = $this->controllerResolver->getController($request);
            //获得传递给控制器的参数。
            $arguments = $this->argumentResolver->getArguments($request,$controller);

            //call_user_func_array — 调用回调函数callback，并把一个数组参数作为回调函数的参数
            $response = call_user_func($controller,$arguments);
        }catch (ResourceNotFoundException $e){
            $response = new Response('not found',404);
        }catch (\Exception $e){
            $response = new Response('an error occurred',500);
        }

        //diapatcher a response event派遣事件
        $this->dispatcher->dispatch('response',new ResponseEvent($response,$request));

        return $response;
    }

}